from tkinter import filedialog, messagebox
import cv2
import numpy as np
from datetime import datetime
import os

file_path = ""  # 存储选择的文件的路径

# 选择要压缩的图像文件
def select_image(selected_file_label):
    global file_path  # 使用全局变量
    file_path = filedialog.askopenfilename()  # 打开文件选择对话框
    print("选择的图像：", file_path)
    update_label(selected_file_label)

# 更新选择文件的标签，如果没有选择文件则显示未选择文件
def update_label(selected_file_label):
    if not file_path:  # 如果没有选择文件
        selected_file_label.config(text="未选择文件", fg="gray")  # 标签显示未选择文件
    else:
        text = file_path
        if len(text) > 30:  # 如果文件名太长，只显示前10个字符和后20个字符
            text = f"{text[:10]}...{text[-20:]}"
        selected_file_label.config(text=text, fg="black")  # 显示文件名

# 对图像进行压缩
def compress_image(compression_var):
    global file_path  # 使用全局变量
    compression_ratio = compression_var.get()
    if not file_path:  # 如果没有选择文件
        print("请先选择图像文件")
        return

    print(f"将要以压缩比{compression_ratio}去压缩图像{file_path}")

    img = cv2.imread(file_path, 0)  # 读取图像
    fCoef = np.fft.fft2(img)  # 对图像进行傅里叶变换
    mag_spec = np.abs(fCoef)  # 取模
    mag_spec_sorted = np.sort(mag_spec.ravel())  # 对模进行排序

    thresh = mag_spec_sorted[int((1 - compression_ratio) * img.size)]  # 计算阈值
    mask = mag_spec > thresh  # 生成掩膜
    fCoef_compressed = fCoef * mask  # 对傅里叶变换后的频域进行压缩
    img_cp = np.fft.ifft2(fCoef_compressed).real  # 对压缩后的频域进行反傅里叶变换

    output_filename = f"{os.path.splitext(file_path)[0]}_{compression_ratio}_{datetime.now().strftime('%Y%m%d')}.png"  # 定义输出文件名
    success = cv2.imwrite(output_filename, img_cp)  # 保存压缩后的图像

    if success:
        messagebox.showinfo(
            "压缩成功", f"压缩成功，已在源文件旁生成文件{os.path.basename(output_filename)}")
        print(f"压缩完成，已保存为{output_filename}")
    else:
        messagebox.showerror("压缩失败", "压缩失败")

# 退出程序
def quit_app(window):
    window.destroy()  # 退出程序